package com.dcy.account.center.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dcy.account.api.api.AccountApi;
import com.dcy.account.api.dto.AccountDTO;
import com.dcy.account.api.model.Account;
import com.dcy.account.center.mapper.AccountMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.hmily.annotation.HmilyTCC;
import org.dromara.hmily.common.exception.HmilyRuntimeException;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author dcy
 * @since 2021-11-16
 */
@Slf4j
@DubboService(version = "1.0.0", timeout = 3000, retries = 0, interfaceClass = AccountApi.class)
public class AccountService extends ServiceImpl<AccountMapper, Account> implements AccountApi {

    /**
     * The Confrim count.
     */
    private static AtomicInteger confrimCount = new AtomicInteger(0);

    @Override
    @HmilyTCC(confirmMethod = "confirm", cancelMethod = "cancel")
    public boolean payment(AccountDTO accountDTO) {
        int count = baseMapper.update(accountDTO);
        log.info("payment {} {}", count, accountDTO);
        if (count > 0) {
            return true;
        } else {
            throw new HmilyRuntimeException("账户扣减异常！");
        }
    }

    @Override
    @HmilyTCC(confirmMethod = "confirm", cancelMethod = "cancel")
    public boolean mockTryPaymentException(AccountDTO accountDTO) {
        throw new HmilyRuntimeException("账户扣减异常！");
    }


    /**
     * Confirm boolean.
     *
     * @param accountDTO the account dto
     * @return the boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean confirm(AccountDTO accountDTO) {
        log.info("============dubbo tcc 执行确认付款接口===============");
        baseMapper.confirm(accountDTO);
        final int i = confrimCount.incrementAndGet();
        log.info("调用了account confirm " + i + " 次");
        return Boolean.TRUE;
    }

    /**
     * Cancel boolean.
     *
     * @param accountDTO the account dto
     * @return the boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean cancel(AccountDTO accountDTO) {
        log.info("============ dubbo tcc 执行取消付款接口===============");
        final Account account = baseMapper.findByUserId(accountDTO.getUserId());
        baseMapper.cancel(accountDTO);
        return Boolean.TRUE;
    }
}
